﻿#include "CLibrary.h"
#include <QDebug>

/// 跨平台宏定义，支持不同平台条件编译
#if defined(_WIN32)
#    include <windows.h>
#elif defined(__linux)
#    include <dlfcn.h>
#endif

std::wstring StringToWString(const std::string & s);
std::string WChar2Ansi(LPCWSTR pwszSrc);

CLibrary::CLibrary(const std::string & fileName) : fileName_(fileName), isLoad_(false)
{
}

CLibrary::~CLibrary()
{
}

void * CLibrary::resolve(const char * symbol)
{
    if (nullptr == lib_ || nullptr == symbol) { return nullptr; }
#if defined(_WIN32)
    return (void *)GetProcAddress((HMODULE)lib_, symbol);
#elif defined(__linux)
    return dlsym(lib_, symbol);
#endif
}

bool CLibrary::load()
{
#if defined(_WIN32)
    lib_ = LoadLibrary(StringToWString(fileName_).c_str());
#    define libErrorText ""
#elif defined(__linux)
    lib_ = dlopen(fileName_.c_str(), RTLD_LAZY);
#    define libErrorText dlerror()
#endif

    if (nullptr == lib_) { qDebug() << "Cannot load lib:" << fileName_.c_str() << libErrorText; }
    else
    {
        isLoad_ = true;
    }

    return isLoad_;
}

bool CLibrary::isLoaded() const
{
    return isLoad_;
}

void CLibrary::setFileName(const std::string & fileName)
{
    fileName_ = fileName;
}

std::string CLibrary::fileName() const
{
    return fileName_;
}

// wstring转换成string
std::string WChar2Ansi(LPCWSTR pwszSrc)
{
    int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, nullptr, 0, nullptr, nullptr);

    if (nLen <= 0) return std::string("");

    char * pszDst = new char[nLen];
    if (nullptr == pszDst) return std::string("");

    WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, nullptr, nullptr);
    pszDst[nLen - 1] = 0;

    std::string strTemp(pszDst);
    delete[] pszDst;

    return strTemp;
}

// string转换车wstring
std::wstring StringToWString(const std::string & s)
{
    std::wstring wszStr;

    int nLength = MultiByteToWideChar(CP_ACP, 0, s.c_str(), -1, nullptr, 0);
    wszStr.resize(nLength);
    LPWSTR lpwszStr = new wchar_t[nLength];
    MultiByteToWideChar(CP_ACP, 0, s.c_str(), -1, lpwszStr, nLength);
    wszStr = lpwszStr;
    delete[] lpwszStr;
    return wszStr;
}
